/**
 * @description lib/signature
 *
 * @author xiaomi
 */
'use strict';

const URL = require('url');
const crypto = require('crypto');
const lodash = require('lodash');

const sortByASCII = function(query) {
    if(!query) {
        return '';
    }

    if(typeof query === 'string') {
        query = '/?' + query.replace(/^\?/, '');

        query = URL.parse(query, true).query;
    }

    let keys = Object.keys(query);

    // sort
    keys.sort();

    return keys.map(k => {
        return `${k}=${query[k]}`;
    })
    .join('&');
};

const signFns = {
    api(data = {}) {
        if(!data.appId || !data.appSecret) {
            throw new Error('appId and appSecret required');
        }

        let tmpArr = [
            data.appId,
            lodash.toUpper(data.method) || 'GET',
            data.path || '/',
            sortByASCII(data.query),
            data.timestamp || ''
        ];

        if(!lodash.isEmpty(data.body) && !data.bodyEscaped) {
            tmpArr.push(JSON.stringify(data.body));
        }

        // sha1 sign
        let signatureCrypto = crypto.createHmac('sha1', data.appSecret || '');
        let tmpStr = tmpArr.join('@');

        signatureCrypto.update(tmpStr, 'utf8');

        let sign = signatureCrypto.digest('hex');

        // upper case
        sign = sign.toUpperCase();

        // // debug
        // console.info('Signature result:', {
        //     data: tmpStr,
        //     sign: sign
        // });

        return sign;
    }
};

module.exports = function(data, fnName) {
    let signFn = signFns[fnName] || signFns.api;

    return signFn(data);
};
